package com.cardone.platform.authority.service;

import java.util.List;
import java.util.Map;
import java.util.UUID;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;

import org.apache.commons.lang3.ArrayUtils;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.transaction.annotation.Transactional;

import com.cardone.common.dto.PaginationDto;
import com.cardone.common.utils.EntityUtils;
import com.cardone.persistent.CommonDtoAttributes;
import com.cardone.platform.authority.dao.PeVaRuTransactModeDao;
import com.cardone.platform.authority.dao.PermissionDao;
import com.cardone.platform.authority.dto.PeVaRuTransactModeDto;
import com.cardone.platform.authority.dto.PermissionDto;

/**
 * 许可服务
 * 
 * @author yaoht
 * 
 */
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class PermissionDefaultService implements PermissionService {
	/**
	 * 许可数据持久
	 */
	private PermissionDao permissionDao;

	/**
	 * 许可、验证规则与处理模式数据持久
	 */
	private PeVaRuTransactModeDao peVaRuTransactModeDao;

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int deletePermissionByCode(@NonNull PermissionDto deletePermission) {
		return this.permissionDao.deleteByCode(deletePermission, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int deletePermissionByIds(@NonNull PermissionDto deletePermission) {
		return this.permissionDao.deleteByIds(deletePermission);
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int deletePeVaRuTransactModeByCode(@NonNull PeVaRuTransactModeDto deletePeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.deleteByCode(deletePeVaRuTransactMode, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int deletePeVaRuTransactModeByIds(@NonNull PeVaRuTransactModeDto deletePeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.deleteByIds(deletePeVaRuTransactMode);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<PermissionDto> findListPermissionByCode(@NonNull PermissionDto findListPermission) {
		return this.permissionDao.findListByCode(PermissionDto.class, findListPermission, new String[] {}, new String[] {});
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<PermissionDto> findListPermissionByName(@NonNull PermissionDto findListPermission) {
		return this.permissionDao.findListByName(PermissionDto.class, findListPermission);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<PeVaRuTransactModeDto> findListPeVaRuTransactModeByCode(@NonNull PeVaRuTransactModeDto findListPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.findListByCode(PeVaRuTransactModeDto.class, findListPeVaRuTransactMode, new String[] {},
		        new String[] {});
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public List<PeVaRuTransactModeDto> findListPeVaRuTransactModeByName(@NonNull PeVaRuTransactModeDto findListPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.findListByName(PeVaRuTransactModeDto.class, findListPeVaRuTransactMode);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PermissionDto findPermissionByCode(@NonNull PermissionDto findPermission) {
		return this.permissionDao.findByCode(PermissionDto.class, findPermission, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PermissionDto findPermissionById(@NonNull PermissionDto findPermission) {
		return this.permissionDao.findByCode(PermissionDto.class, findPermission, null, CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PeVaRuTransactModeDto findPeVaRuTransactModeByCode(@NonNull PeVaRuTransactModeDto findPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.findByCode(PeVaRuTransactModeDto.class, findPeVaRuTransactMode, null,
		        CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PeVaRuTransactModeDto findPeVaRuTransactModeById(@NonNull PeVaRuTransactModeDto findPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.findByCode(PeVaRuTransactModeDto.class, findPeVaRuTransactMode, null,
		        CommonDtoAttributes.id.name());
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<PermissionDto> paginationPermissionByCode(@NonNull PermissionDto paginationPermission) {
		return this.permissionDao.paginationByCode(PermissionDto.class, paginationPermission);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationPermissionByName(@NonNull PermissionDto paginationPermission) {
		return this.permissionDao.paginationByName(paginationPermission);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<PeVaRuTransactModeDto> paginationPeVaRuTransactModeByCode(
	        @NonNull PeVaRuTransactModeDto paginationPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.paginationByCode(PeVaRuTransactModeDto.class, paginationPeVaRuTransactMode);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public PaginationDto<Map<String, Object>> paginationPeVaRuTransactModeByName(
	        @NonNull PeVaRuTransactModeDto paginationPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.paginationByName(paginationPeVaRuTransactMode);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readPermissionByCodeNqId(@NonNull PermissionDto readPermission) {
		return this.permissionDao.readByCodeNqId(Integer.class, readPermission);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readPermissionByName(@NonNull PermissionDto readPermission) {
		return this.permissionDao.readByName(Integer.class, null, readPermission);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readPeVaRuTransactModeByCodeNqId(@NonNull PeVaRuTransactModeDto readPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.readByCodeNqId(Integer.class, readPeVaRuTransactMode);
	}

	@Override
	@Cacheable(value = PermissionService.BEAN_ID, key = com.cardone.common.cache.Constants.KEY_1)
	public Integer readPeVaRuTransactModeByName(@NonNull PeVaRuTransactModeDto readPeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.readByName(Integer.class, null, readPeVaRuTransactMode);
	}

	@Override
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public void reload() {
		this.permissionDao.reload();

		this.peVaRuTransactModeDao.reload();
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public PermissionDto savePermissionByIdOrCode(@NonNull PermissionDto savePermission) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(savePermission, CommonDtoAttributes.code.name());

		final PermissionDto oldPermission = this.permissionDao.findByCode(PermissionDto.class, savePermission, null,
		        whereAndEqProperties);

		if (oldPermission == null) {
			savePermission.setId(UUID.randomUUID().toString());

			this.permissionDao.insertByCode(savePermission);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(savePermission);

			return this.permissionDao.findByCode(PermissionDto.class, savePermission, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        savePermission);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(savePermission, oldPermission,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldPermission;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldPermission);

		com.cardone.common.utils.BeanUtils.copyProperties(oldPermission, savePermission, notNullIdProperties);

		this.permissionDao.updateByCode(savePermission, updateProperties, notNullIdProperties);

		return this.permissionDao.findByCode(PermissionDto.class, oldPermission, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public PermissionDto savePermissionByName(@NonNull PermissionDto savePermission) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(savePermission, CommonDtoAttributes.code.name());

		final PermissionDto oldPermission = this.permissionDao.findByCode(PermissionDto.class, savePermission, null,
		        whereAndEqProperties);

		if (oldPermission == null) {
			savePermission.setId(UUID.randomUUID().toString());

			this.permissionDao.insertByCode(savePermission);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(savePermission);

			return this.permissionDao.findByCode(PermissionDto.class, savePermission, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        savePermission);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(savePermission, oldPermission,
		        useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldPermission;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldPermission);

		com.cardone.common.utils.BeanUtils.copyProperties(oldPermission, savePermission, notNullIdProperties);

		this.permissionDao.updateByCode(savePermission, updateProperties, notNullIdProperties);

		return this.permissionDao.findByCode(PermissionDto.class, oldPermission, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public PeVaRuTransactModeDto savePeVaRuTransactModeByIdOrCode(@NonNull PeVaRuTransactModeDto savePeVaRuTransactMode) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(savePeVaRuTransactMode, CommonDtoAttributes.code.name());

		final PeVaRuTransactModeDto oldPeVaRuTransactMode = this.peVaRuTransactModeDao.findByCode(PeVaRuTransactModeDto.class,
		        savePeVaRuTransactMode, null, whereAndEqProperties);

		if (oldPeVaRuTransactMode == null) {
			savePeVaRuTransactMode.setId(UUID.randomUUID().toString());

			this.peVaRuTransactModeDao.insertByCode(savePeVaRuTransactMode);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(savePeVaRuTransactMode);

			return this.peVaRuTransactModeDao
			        .findByCode(PeVaRuTransactModeDto.class, savePeVaRuTransactMode, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        savePeVaRuTransactMode);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(savePeVaRuTransactMode,
		        oldPeVaRuTransactMode, useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldPeVaRuTransactMode;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldPeVaRuTransactMode);

		com.cardone.common.utils.BeanUtils.copyProperties(oldPeVaRuTransactMode, savePeVaRuTransactMode, notNullIdProperties);

		this.peVaRuTransactModeDao.updateByCode(savePeVaRuTransactMode, updateProperties, notNullIdProperties);

		return this.peVaRuTransactModeDao.findByCode(PeVaRuTransactModeDto.class, oldPeVaRuTransactMode, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public PeVaRuTransactModeDto savePeVaRuTransactModeByName(@NonNull PeVaRuTransactModeDto savePeVaRuTransactMode) {
		final String[] whereAndEqProperties = EntityUtils.getWhereProperties(savePeVaRuTransactMode, CommonDtoAttributes.code.name());

		final PeVaRuTransactModeDto oldPeVaRuTransactMode = this.peVaRuTransactModeDao.findByCode(PeVaRuTransactModeDto.class,
		        savePeVaRuTransactMode, null, whereAndEqProperties);

		if (oldPeVaRuTransactMode == null) {
			savePeVaRuTransactMode.setId(UUID.randomUUID().toString());

			this.peVaRuTransactModeDao.insertByCode(savePeVaRuTransactMode);

			final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(savePeVaRuTransactMode);

			return this.peVaRuTransactModeDao
			        .findByCode(PeVaRuTransactModeDto.class, savePeVaRuTransactMode, null, notNullIdProperties);
		}

		final String[] useProperties = EntityUtils.addNotNullTimeSegmentProperties(new String[] { CommonDtoAttributes.parentId.name(),
		        CommonDtoAttributes.typeId.name(), CommonDtoAttributes.code.name(), CommonDtoAttributes.name.name(),
		        CommonDtoAttributes.orderCode.name(), CommonDtoAttributes.value.name(), CommonDtoAttributes.remark.name() },
		        savePeVaRuTransactMode);

		final String[] updateProperties = com.cardone.common.utils.BeanUtils.diffProperties(savePeVaRuTransactMode,
		        oldPeVaRuTransactMode, useProperties);

		if (ArrayUtils.isEmpty(updateProperties)) {
			return oldPeVaRuTransactMode;
		}

		final String[] notNullIdProperties = EntityUtils.getNotNullIdProperties(oldPeVaRuTransactMode);

		com.cardone.common.utils.BeanUtils.copyProperties(oldPeVaRuTransactMode, savePeVaRuTransactMode, notNullIdProperties);

		this.peVaRuTransactModeDao.updateByCode(savePeVaRuTransactMode, updateProperties, notNullIdProperties);

		return this.peVaRuTransactModeDao.findByCode(PeVaRuTransactModeDto.class, oldPeVaRuTransactMode, null, notNullIdProperties);
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int updatePermissionByCode(@NonNull PermissionDto updatePermission) {
		return this.permissionDao.updateByCode(updatePermission, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int updatePermissionByIds(@NonNull PermissionDto updatePermission) {
		return this.permissionDao.updateByIds(updatePermission);
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int updatePeVaRuTransactModeByCode(@NonNull PeVaRuTransactModeDto updatePeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.updateByCode(updatePeVaRuTransactMode, new String[] {}, new String[] {});
	}

	@Override
	@Transactional
	@CacheEvict(value = PermissionService.BEAN_ID, allEntries = true)
	public int updatePeVaRuTransactModeByIds(@NonNull PeVaRuTransactModeDto updatePeVaRuTransactMode) {
		return this.peVaRuTransactModeDao.updateByIds(updatePeVaRuTransactMode);
	}
}